﻿#if ODIN_INSPECTOR
using System;
using System.Linq;
using Sirenix.OdinInspector.Editor;
using Sirenix.Utilities;
using Sirenix.Utilities.Editor;
using UnityEngine;
using Object = UnityEngine.Object;

#pragma warning disable 618

[DrawerPriority(0, 200)]
public class PageSliderAttributeDrawer : OdinAttributeDrawer<PageSliderAttribute> {
    private static GUIStyle                                          titleStyle;
    private static SlidePageNavigationHelper<InspectorProperty>      currentSlider;
    private static InspectorProperty                                 currentDrawingPageProperty;
    private        SlidePageNavigationHelper<InspectorProperty>.Page page;
    private        GUIContent                                        pageLabel;
    private        SlidePageNavigationHelper<InspectorProperty>      slider;

    protected override bool CanDrawAttributeProperty(InspectorProperty property)
    {
        return !(property.ChildResolver is ICollectionResolver);
    }

    protected override void Initialize()
    {
        titleStyle = titleStyle ?? new GUIStyle("ShurikenModuleTitle");
    }

    protected override void DrawPropertyLayout(GUIContent label)
    {
        if (Property.ValueEntry.WeakSmartValue == null) {
            CallNextDrawer(label);
            return;
        }

        UpdateBreadcrumbLabel(label);

        if (currentSlider == null) {
            DrawPageSlider(label);
        }
        else if (currentDrawingPageProperty == Property) {
            CallNextDrawer(null);
        }
        else {
            if (GUILayout.Button(new GUIContent(GetLabelText(label)), titleStyle)) {
                currentSlider.PushPage(Property, Guid.NewGuid().ToString());
                currentSlider.EnumeratePages.Last();
                page      = currentSlider.EnumeratePages.Last();
                page.Name = GetLabelText(label);
                pageLabel = label;
            }
        }
    }

    private void UpdateBreadcrumbLabel(GUIContent label)
    {
        if (Event.current.type != EventType.Layout) return;
        if (page == null) return;
        if (pageLabel != null && pageLabel != Property.Label) return;

        var newLabel = GetLabelText(label ?? pageLabel);

        if (newLabel != page.Name) {
            page.Name = newLabel;
            page.GetType().GetField("TitleWidth", Flags.AllMembers).SetValue(page, null);
        }
    }

    private void DrawPageSlider(GUIContent label)
    {
        try {
            if (slider == null) {
                slider = new SlidePageNavigationHelper<InspectorProperty>();
                slider.PushPage(Property, Guid.NewGuid().ToString());
                page      = slider.EnumeratePages.Last();
                page.Name = GetLabelText(label);
            }

            currentSlider = slider;

            SirenixEditorGUI.BeginBox();
            SirenixEditorGUI.BeginToolbarBoxHeader();
            {
                var rect = GUILayoutUtility.GetRect(0, 20);
                rect.x -= 5;
                slider.DrawPageNavigation(rect);
            }
            SirenixEditorGUI.EndToolbarBoxHeader();
            {
                slider.BeginGroup();
                foreach (var p in slider.EnumeratePages) {
                    if (p.BeginPage()) {
                        if (p.Value == Property) {
                            CallNextDrawer(null);
                        }
                        else {
                            currentDrawingPageProperty = p.Value;
                            if (p.Value.Tree != Property.Tree) InspectorUtilities.BeginDrawPropertyTree(p.Value.Tree, true);
                            p.Value.Draw(null);

                            if (p.Value.Tree != Property.Tree) InspectorUtilities.EndDrawPropertyTree(p.Value.Tree);
                            currentDrawingPageProperty = null;
                        }
                    }

                    p.EndPage();
                }

                slider.EndGroup();
            }
            SirenixEditorGUI.EndBox();
        }
        finally {
            currentSlider = null;
        }
    }

    private string GetLabelText(GUIContent label)
    {
        if (label != null) return label.text;

        var val = Property.ValueEntry.WeakSmartValue;
        if (val == null) return "Null";
        var uObj = val as Object;
        if (uObj) {
            if (string.IsNullOrEmpty(uObj.name))
                return uObj.ToString();
            return uObj.name;
        }

        return val.ToString();
    }
}
#endif